from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from datetime import datetime

from database.connection import get_db
from database.models import SystemConfig
from models.system_config import SystemConfigCreate, SystemConfigUpdate, SystemConfigResponse, EmailSendRequest
from routers.admin import verify_admin_permission
# 明文存储敏感字段（不再进行加密）

router = APIRouter(prefix="/config", tags=["系统配置"])


@router.get("/", summary="获取当前系统配置（管理员）")
async def get_system_config(
    db: Session = Depends(get_db),
    admin_user = Depends(verify_admin_permission)
):
    """
    获取当前激活的系统配置
    若不存在记录，返回空数据结构
    """
    try:
        cfg = db.query(SystemConfig).filter(SystemConfig.is_active == True).order_by(SystemConfig.updated_at.desc()).first()
        if not cfg:
            return {"code": 200, "msg": "暂无系统配置", "data": {}}
        return {"code": 200, "msg": "获取成功", "data": SystemConfigResponse.from_orm(cfg)}
    except Exception as e:
        return {"code": 500, "msg": f"获取系统配置失败: {str(e)}"}


@router.put("/", summary="保存系统配置（管理员）")
async def save_system_config(
    payload: SystemConfigUpdate,
    db: Session = Depends(get_db),
    admin_user = Depends(verify_admin_permission)
):
    """
    保存或更新系统配置（仅管理员）
    - 若存在激活记录：进行字段级更新（敏感字段入库前加密）
    - 若不存在：创建新记录并设为激活
    """
    try:
        current = db.query(SystemConfig).filter(SystemConfig.is_active == True).order_by(SystemConfig.updated_at.desc()).first()

        def to_update_dict() -> dict:
            data = payload.dict(exclude_unset=True)
            # 直接明文存储敏感字段
            return data

        if current:
            update_data = to_update_dict()
            if not update_data:
                return {"code": 400, "msg": "未提供需要更新的字段"}
            update_data["updated_at"] = datetime.now()
            for field, value in update_data.items():
                setattr(current, field, value)
            db.commit()
            db.refresh(current)
            return {"code": 200, "msg": "更新成功", "data": SystemConfigResponse.from_orm(current)}
        else:
            create_payload = SystemConfigCreate(**payload.dict(exclude_unset=True))
            new_cfg = SystemConfig(
                smtp_server=create_payload.smtp_server or 'smtp.qq.com',
                smtp_port=int(create_payload.smtp_port or 587),
                email=create_payload.email,
                email_password=create_payload.email_password,
                phone_number=create_payload.phone_number,
                douyin_password=create_payload.douyin_password,
                xhs_cookie=create_payload.xhs_cookie,
                is_active=True,
                created_at=datetime.now(),
                updated_at=datetime.now()
            )
            db.add(new_cfg)
            db.commit()
            db.refresh(new_cfg)
            return {"code": 200, "msg": "创建成功", "data": SystemConfigResponse.from_orm(new_cfg)}
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"保存系统配置失败: {str(e)}")


def _send_mail_via_config(cfg: SystemConfig, to: str, subject: str, body: str) -> bool:
    """
    使用系统配置通过SMTP发送邮件，返回是否成功发送
    为避免邮件已发送但关闭阶段异常导致500，显式管理连接并忽略关闭异常
    """
    import smtplib
    from email.message import EmailMessage

    server = str(cfg.smtp_server or '').strip()
    port = int(cfg.smtp_port or 0)
    user = str(cfg.email or '').strip()
    password = str(cfg.email_password or '').strip()

    if not server or not port or not user or not password:
        raise RuntimeError('系统配置不完整，缺少SMTP服务器/端口/邮箱/密码')

    msg = EmailMessage()
    msg['From'] = user
    msg['To'] = to
    msg['Subject'] = subject
    msg.set_content(body)

    sent = False
    smtp = None
    try:
        if port == 465:
            smtp = smtplib.SMTP_SSL(server, port, timeout=20)
        else:
            smtp = smtplib.SMTP(server, port, timeout=20)
            smtp.ehlo()
            try:
                smtp.starttls()
                smtp.ehlo()
            except Exception:
                pass
        smtp.login(user, password)
        smtp.send_message(msg)
        sent = True
        return sent
    finally:
        try:
            if smtp:
                try:
                    smtp.quit()
                except Exception:
                    smtp.close()
        except Exception:
            pass


@router.post("/send-email", summary="使用系统配置发送邮件（管理员）")
async def send_email(
    payload: EmailSendRequest,
    db: Session = Depends(get_db),
    admin_user = Depends(verify_admin_permission)
):
    """
    使用当前激活的系统配置发送邮件
    接收收件人、主题、正文
    """
    try:
        cfg = db.query(SystemConfig).filter(SystemConfig.is_active == True).order_by(SystemConfig.updated_at.desc()).first()
        if not cfg:
            return {"code": 400, "msg": "暂无系统配置"}
        ok = _send_mail_via_config(cfg, payload.to, payload.subject, payload.body)
        if ok:
            return {"code": 200, "msg": "邮件发送成功", "data": {"to": payload.to}}
        else:
            raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="邮件发送失败")
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"邮件发送失败: {str(e)}")


@router.post("/test-email", summary="发送测试邮件到指定邮箱（管理员）")
async def send_test_email(
    db: Session = Depends(get_db),
    admin_user = Depends(verify_admin_permission)
):
    """
    使用当前激活的系统配置发送测试邮件到 2504880498@qq.com
    """
    try:
        cfg = db.query(SystemConfig).filter(SystemConfig.is_active == True).order_by(SystemConfig.updated_at.desc()).first()
        if not cfg:
            return {"code": 400, "msg": "暂无系统配置"}
        ok = _send_mail_via_config(cfg, "2504880498@qq.com", "AIGD100 测试邮件", "这是一封测试邮件。")
        if ok:
            return {"code": 200, "msg": "测试邮件发送成功", "data": {"to": "2504880498@qq.com"}}
        else:
            raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="测试邮件发送失败")
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"测试邮件发送失败: {str(e)}")
